import Vue from 'vue'
import { CHG_UPLOADING } from '@/store/mutations'
import { getSignature } from '@/api/upload'
export default Vue.extend({
  data () {
    return {
      isScriptLoaded: false,
      // scriptUrl: 'https://cdn.bootcss.com/jquery/3.3.1/jquery.slim.min.js',
      scriptUrl: '//imgcache.qq.com/open/qcloud/js/vod/sdk/ugcUploader.js',
      failedFile: [] as FailedFile,
      unStartFile: [] as UnStartFile[],
      fileList: [] as FileStatus[], // status: 0: 等待上传 1: 开始上传 2：完成上传 3：上传失败
      concurrency: 5,
      onProgressCount: 0,
    }
  },
  methods: {
    createScript () {
      let uploadScript = document.getElementById('uploadScript') as HTMLScriptElement
      if (uploadScript) {
        const isLoaded = typeof qcVideo !== 'undefined'
        this.isScriptLoaded = isLoaded
        if (isLoaded) {
          this.start()
        } else {
          this.$parent.$parent.$on('scriptLoad', () => {
            this.isScriptLoaded = true
            this.start()
          })
        }
        return
      }
      const uploadScript0 = document.createElement('script')
      uploadScript0.id = 'uploadScript'
      uploadScript0.type = 'text/javascript'
      uploadScript0.onload = this.onScriptLoaded
      uploadScript0.src = this.scriptUrl
      document.body.appendChild(uploadScript0)
    },
    onScriptLoaded () {
      this.isScriptLoaded = true
      this.$parent.$parent.$emit('scriptLoad')
      this.start()
    },
    getSignature (callback: any) {
      getSignature().then(res => {
        callback(res.Signature)
      })
    },
    pushFile (files: File[]) {
      const fileMaxIndex = this.fileList.length - 1
      const fileList: FileStatus[] = files.map((file, index) => {
        const nameMatch = file.name.match(/(.{1,50}).*\.\w+$/)
        return {
          name: nameMatch ? nameMatch[1] : file.name,
          status: 0,
          fileId: fileMaxIndex + index,
          size: file.size / 1024,
        }
      })
      const unStartFile = files.map((file, index) => {
        return { file, fileId: fileMaxIndex + index }
      })
      this.$set(this.$data, 'unStartFile', [...this.unStartFile, ...unStartFile])
      this.$set(this.$data, 'fileList', [...this.fileList, ...fileList])
      this.isScriptLoaded && this.start()
    },
    start () {
      while (
        this.concurrency > this.onProgressCount &&
        this.unStartFile.length &&
        this.$store.state.uploadingCount < 5
      ) {
        const file2upload = this.unStartFile[0]
        this.$set(this.$data, 'unStartFile', this.unStartFile.slice(1))
        this.uploader(file2upload)
        this.onProgressCount++
        this.$store.commit(CHG_UPLOADING, 1)
      }
    },
    restart (fileId: number) {
      const failedFile: UnStartFile = { fileId, file: this.failedFile[fileId] }
      this.$set(this.$data, 'unStartFile', [failedFile, ...this.unStartFile])
      this.start()
    },
    statusChange (fileObj: UnStartFile, status: number, info: any) {
      const files = this.fileList
      let i = 0
      let newFile
      for (let l = files.length; i < l; i++) {
        if (files[i].fileId === fileObj.fileId) {
          if (status === 1) {
            newFile = {
              ...files[i],
              curr: info.curr,
              shacurr: info.shacurr,
              cos: info.cos,
              taskId: info.taskId,
              status,
            }
          } else if (status === 2) {
            // newFile = { ...files[i], id: info.fileId, videoUrl: info.videoUrl, status }
            // 上传成功不改变状态，还是上传中1
            newFile = { ...files[i], id: info.fileId, videoUrl: info.videoUrl, index: i, up: true }
            this.$emit('uploadSuccess', newFile)
            this.$store.commit(CHG_UPLOADING, -1)
          } else if (status === 3) {
            newFile = { ...files[i], err: info, status }
            this.$set(this.$data, 'failedFile',
              { ...this.failedFile, [fileObj.fileId]: fileObj.file })
            this.$store.commit(CHG_UPLOADING, -1)
          }
          break
        }
      }
      this.$set(this.$data.fileList, i, newFile)
    },
    // changeState2Success (newFile: any) {
    //   this.$set(this.$data.fileList, newFile.index, { ...newFile, status: 2 })
    // },
    changeState2Success () {
      const fileList = this.fileList.filter(f => f.up)
      fileList.forEach(f => {
        delete f.up
        console.log(f)
        this.$set(this.$data.fileList, f.index!, { ...f, status: 2 })
      })
    },
    cancelUpload (cos: any, taskId: any, index?: number) {
      qcVideo.ugcUploader.cancel({
        cos,
        taskId,
      })
      if (typeof index !== 'undefined') {
        this.fileList.splice(index, 1)
      }
    },
    cancelAllUpload () {
      this.$set(this.$data, 'unStartFile', [])
      this.fileList.forEach(f => {
        if (f.status === 1) {
          this.cancelUpload(f.cos, f.taskId)
        }
      })
      this.$set(this.$data, 'fileList', [])
    },
    onFinally (name: string) {
      this.onProgressCount--
      this.start()
      if (this.onProgressCount < 5 && this.$store.state.uploadingCount < 5) {
        this.$parent.$parent.$emit('startUpload')
      }
    },
    uploader (fileObj: UnStartFile) {
      qcVideo.ugcUploader.start({
        videoFile: fileObj.file,
        getSignature: this.getSignature,
        error: (e: any) => {
          this.statusChange(fileObj, 3, e.msg)
          this.onFinally(fileObj.file.name)
        },
        finish: (res: any) => {
          this.statusChange(fileObj, 2, res)
          this.onFinally(fileObj.file.name)
        },
        progress: (res: any) => {
          this.statusChange(fileObj, 1, res)
        },
      })
    },
  },
  created () {
    this.createScript()
    this.$parent.$parent.$on('startUpload', () => {
      this.start()
    })
  },
})

declare const qcVideo: any
interface UnStartFile {
  file: File
  fileId: number
}
interface FailedFile {
  [key: number]: File
}
interface FileStatus {
  name: string
  status: number
  fileId: number
  size: number
  curr?: number
  videoUrl?: string
  id?: string
  err?: string
  cos?: any
  taskId?: number
  index?: number // 索引
  up?: boolean // 已成功上传
}
